#!/usr/bin/perl -w 

use strict;
#use diagnostics; # only debug mode
use LWP::UserAgent; 
use HTTP::Response; 
use URI::Heuristic;
use WebService::Validator::Feed::W3C;


my $SAVE = 1; # 0 = don't save the file
my $DIR = "/tmp";
my $FILE = "/data";
my $TIME = "_".&get_time();
my $EXT = ".xml";
my $FILE_TO_SAVE = $DIR.$FILE.$TIME.$EXT; # ex: /tmp/data_109120145530.xml
my $PROXY = ''; # ex.: http://myproxy.mydomain.org:3128


my $raw_url = shift  or die "usage: $0 url\n";

# http request
my $ua = &crea_ua();
my $content = &http_request($ua, $raw_url);

# http2file
&write_file($content) if $SAVE;

# validate
my $val = WebService::Validator::Feed::W3C->new($ua);
&validate_feed($val, $content);

exit;


sub crea_ua() {
  my $ua = LWP::UserAgent->new( );
  $ua->timeout(10);
  if ($PROXY) {
     $ua->proxy(['http', 'ftp'], $PROXY);
  } else  {
    $ua->env_proxy;
  }
  $ua->agent("Antani/v9.14 Platinum");
  return $ua;
}

sub http_request($$) {
  my $ua 	= shift;
  my $raw_url 	= shift;

  my $url = URI::Heuristic::uf_urlstr($raw_url);
  $| = 1;                                  # to flush next line 
  printf "\nValidating %s =>\n\t", $url;
  my $response = $ua->get($url, Referer => "http://alfa.beta.oz");
  if ($response->is_error( )) {
      print "Request error!\n"; 
      die $response->status_line;
  } 
  return $response->content( );
}

sub write_file($) {
  my $content = shift;
  open (F, ">$FILE_TO_SAVE");
  print F "$content";
  close (F); 

  print "\n\tWrote file: ". $FILE_TO_SAVE . "\n";
}

sub validate_feed($$) {
  my $val 	  = shift;
  my $validate_me = shift;

  my $success = $val->validate(string => $validate_me);

  if ($success) {
    if ($val->errorcount != 0) {
      &show_errors($val);
    } else { 
      printf "\n\tFeed is valid. "; 
    }
    if ($val->warningcount != 0) { 
      &show_warnings($val);
    } 
    printf "\n";
  } else {
    print "\n\tSorry! could not validate\n\n"; 
  }

}

sub show_errors($) {
  my $val = shift;
  printf "Invalid! %u error(s)", $val->errorcount; 
  printf "\n\t  * %s at line: %s column: %s \n", $_->{text}, $_->{line}, $_->{column} foreach $val->errors;
}


sub show_warnings($) {
  my $val = shift;
  my @warnings = $val->warnings;
  if (scalar(@warnings)>0) {
    printf "\n\t(%u warning(s))", $val->warningcount;
    printf "\n\t  * %s at line: %s column: %s \n", $_->{text}, $_->{line}, $_->{column} foreach $val->warnings;
  }
}


sub get_time() {
  my $sec, my $min, my $hour, my $mday, my $mon, my $year, my $wday, my $yday, my $isdst;
  ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime();
  return $year.$mon.$mday.$hour.$min.$sec;
}